from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Request
from fastapi.responses import HTMLResponse, RedirectResponse, FileResponse, JSONResponse
from sqlalchemy.orm import Session
from typing import List, Optional
import os
import shutil
from pathlib import Path
from pydantic import BaseModel

from ..models import get_db, StaticPage, WebsiteConfig
from ..templates import templates
from ..config import PAGE_SIZE

# 状态切换请求模型
class ToggleStatusRequest(BaseModel):
    new_status: bool

# 静态文件上传路径
STATIC_FILE_UPLOAD_PATH = "static/pages"

router = APIRouter()

# 确保上传目录存在
os.makedirs(STATIC_FILE_UPLOAD_PATH, exist_ok=True)

# 不限制文件类型，支持任意文件上传

@router.get("/admin/static-pages", response_class=HTMLResponse)
def static_pages_list(request: Request, db: Session = Depends(get_db), page: int = 1):
    """静态网页列表页面，支持分页"""
    # 获取网站配置
    config = db.query(WebsiteConfig).first() or WebsiteConfig()
    
    # 使用配置的每页显示数量
    page_size = PAGE_SIZE
    
    # 查询总记录数
    total_count = db.query(StaticPage).count()
    total_pages = (total_count + page_size - 1) // page_size  # 向上取整计算总页数
    
    # 确保page在有效范围内
    if page < 1:
        page = 1
    if page > total_pages and total_pages > 0:
        page = total_pages
    
    # 获取当前页数据
    offset = (page - 1) * page_size
    pages = db.query(StaticPage).order_by(StaticPage.id).offset(offset).limit(page_size).all()
    
    return templates.TemplateResponse(
        "admin/static_pages/list.html",
        {
            "request": request, 
            "config": config,
            "pages": pages,
            "current_page": page,
            "total_pages": total_pages
        }
    )

@router.post("/admin/static-pages/batch-delete")
async def static_pages_batch_delete(request: Request, db: Session = Depends(get_db)):
    """批量删除静态网页"""
    from fastapi import Form
    from typing import List
    import asyncio
    
    form_data = await request.form()
    page_ids = form_data.getlist("page_ids")
    
    if not page_ids:
        return {"success": False, "message": "请选择要删除的静态网页"}
    
    try:
        # 首先获取所有要删除的页面信息
        pages = db.query(StaticPage).filter(StaticPage.id.in_(page_ids)).all()
        
        if not pages:
            return {"success": False, "message": "未找到指定的静态网页"}
        
        # 删除相关文件和数据库记录
        for page in pages:
            # 删除页面目录
            page_dir = os.path.join(STATIC_FILE_UPLOAD_PATH, page.directory)
            if os.path.exists(page_dir):
                shutil.rmtree(page_dir)
            
            # 删除数据库记录
            db.delete(page)
        
        db.commit()
        return {"success": True, "message": f"成功删除 {len(pages)} 个静态网页"}
    except Exception as e:
        db.rollback()
        return {"success": False, "message": f"删除失败: {str(e)}"}


@router.get("/admin/static-pages/add", response_class=HTMLResponse)
def static_pages_add_form(request: Request, db: Session = Depends(get_db)):
    """添加静态网页表单"""
    # 获取网站配置
    config = db.query(WebsiteConfig).first() or WebsiteConfig()
    return templates.TemplateResponse(
        "admin/static_pages/form.html",
        {"request": request, "config": config, "page": None, "action": "/admin/static-pages/add"}
    )

@router.post("/admin/static-pages/add")
def static_pages_add(
    name: str = Form(...),
    directory: str = Form(...),
    description: str = Form(""),
    db: Session = Depends(get_db)
):
    """添加静态网页"""
    # 检查目录是否已存在
    existing_page = db.query(StaticPage).filter(
        StaticPage.directory == directory
    ).first()
    
    if existing_page:
        raise HTTPException(status_code=400, detail="页面目录已存在")
    
    # 创建页面目录
    page_dir = os.path.join(STATIC_FILE_UPLOAD_PATH, directory)
    os.makedirs(page_dir, exist_ok=True)
    
    # 创建静态页面记录，默认启用新页面
    db_page = StaticPage(
        name=name,
        directory=directory,
        description=description,
        status=True
    )
    db.add(db_page)
    db.commit()
    
    return RedirectResponse(url="/admin/static-pages", status_code=303)

@router.get("/admin/static-pages/edit/{page_id}", response_class=HTMLResponse)
def static_pages_edit_form(page_id: int, request: Request, db: Session = Depends(get_db)):
    """编辑静态网页表单"""
    # 获取网站配置
    config = db.query(WebsiteConfig).first() or WebsiteConfig()
    
    page = db.query(StaticPage).filter(StaticPage.id == page_id).first()
    if not page:
        raise HTTPException(status_code=404, detail="静态页面不存在")
    
    return templates.TemplateResponse(
        "admin/static_pages/form.html",
        {"request": request, "config": config, "page": page, "action": f"/admin/static-pages/edit/{page_id}"}
    )

@router.post("/admin/static-pages/edit/{page_id}")
def static_pages_edit(
    page_id: int,
    name: str = Form(...),
    directory: str = Form(...),
    description: str = Form(""),
    db: Session = Depends(get_db)
):
    """编辑静态网页"""
    page = db.query(StaticPage).filter(StaticPage.id == page_id).first()
    if not page:
        raise HTTPException(status_code=404, detail="静态页面不存在")
    
    # 检查目录是否被其他页面使用
    existing_page = db.query(StaticPage).filter(
        StaticPage.directory == directory,
        StaticPage.id != page_id
    ).first()
    
    if existing_page:
        raise HTTPException(status_code=400, detail="页面目录已存在")
    
    # 如果目录改变，需要重命名文件夹
    if page.directory != directory:
        old_dir = os.path.join(STATIC_FILE_UPLOAD_PATH, page.directory)
        new_dir = os.path.join(STATIC_FILE_UPLOAD_PATH, directory)
        
        if os.path.exists(old_dir):
            os.rename(old_dir, new_dir)
    
    # 更新页面信息
    page.name = name
    page.directory = directory
    page.description = description
    # status保持不变，使用原有值
    
    
    db.commit()
    
    return RedirectResponse(url="/admin/static-pages", status_code=303)

@router.post("/admin/static-pages/toggle-status/{page_id}")
async def static_pages_toggle_status(page_id: int, request_data: ToggleStatusRequest, db: Session = Depends(get_db)):
    try:
        # 查找静态页面
        page = db.query(StaticPage).filter(StaticPage.id == page_id).first()
        
        if not page:
            return JSONResponse(
                content={"success": False, "message": "静态页面不存在"},
                status_code=404
            )
        
        # 更新状态
        page.status = request_data.new_status
        db.commit()
        
        status_text = "启用" if request_data.new_status else "禁用"
        return JSONResponse(
            content={"success": True, "message": f"静态页面{status_text}成功"}
        )
    except Exception as e:
        db.rollback()
        return JSONResponse(
            content={"success": False, "message": f"状态切换失败: {str(e)}"},
            status_code=500
        )

@router.post("/admin/static-pages/delete/{page_id}")
async def static_pages_delete(page_id: int, db: Session = Depends(get_db)):
    try:
        # 开始事务
        with db.begin():
            # 查找要删除的静态页面
            page = db.query(StaticPage).filter(StaticPage.id == page_id).first()
            
            if not page:
                return JSONResponse(
                    content={"success": False, "message": "静态页面不存在"},
                    status_code=404
                )
            
            # 删除页面目录（如果存在）
            page_dir = os.path.join(STATIC_FILE_UPLOAD_PATH, page.directory)
            
            if os.path.exists(page_dir):
                shutil.rmtree(page_dir)
            
            # 从数据库中删除记录
            db.delete(page)
        
        return JSONResponse(
            content={"success": True, "message": "静态页面删除成功"}
        )
    except Exception as e:
        # 事务回滚已在with db.begin()中自动处理
        return JSONResponse(
            content={"success": False, "message": f"删除失败: {str(e)}"},
            status_code=500
        )

@router.get("/admin/static-pages/files/{page_id}", response_class=HTMLResponse)
def static_pages_files_list(page_id: int, request: Request, page: int = 1, db: Session = Depends(get_db)):
    """查看静态网页文件列表（带分页）"""
    # 获取网站配置
    config = db.query(WebsiteConfig).first() or WebsiteConfig()
    
    # 查询页面对象
    static_page = db.query(StaticPage).filter(StaticPage.id == page_id).first()
    if not static_page:
        raise HTTPException(status_code=404, detail="静态页面不存在")
    
    # 列出页面目录下的所有文件
    page_dir = os.path.join(STATIC_FILE_UPLOAD_PATH, static_page.directory)
    files = []
    
    if os.path.exists(page_dir):
        for root, _, filenames in os.walk(page_dir):
            for filename in filenames:
                file_path = os.path.join(root, filename)
                # 计算相对路径
                relative_path = os.path.relpath(file_path, page_dir)
                files.append({
                    "name": filename,
                    "path": relative_path,
                    "size": os.path.getsize(file_path),
                    "url": f"/static/pages/{static_page.directory}/{relative_path}"
                })
    
    # 排序文件（按文件名）
    files.sort(key=lambda x: x["name"])
    
    # 使用配置的每页显示数量
    items_per_page = PAGE_SIZE
    total_files = len(files)
    total_pages = (total_files + items_per_page - 1) // items_per_page  # 向上取整
    
    # 确保页码有效
    if page < 1:
        page = 1
    elif page > total_pages:
        page = total_pages
    
    # 计算分页起始和结束索引
    start_index = (page - 1) * items_per_page
    end_index = start_index + items_per_page
    paginated_files = files[start_index:end_index]
    
    return templates.TemplateResponse(
        "admin/static_pages/files.html",
        {
            "request": request, 
            "config": config,
            "page_id": page_id,
            "static_page": static_page,
            "files": paginated_files,
            "total_files": total_files,
            "current_page": page,
            "total_pages": total_pages
        }
    )

@router.post("/admin/static-pages/upload/{page_id}")
async def static_pages_upload(
    page_id: int,
    files: List[UploadFile] = File(...),
    db: Session = Depends(get_db)
):
    """上传静态网页文件"""
    page = db.query(StaticPage).filter(StaticPage.id == page_id).first()
    if not page:
        raise HTTPException(status_code=404, detail="静态页面不存在")
    
    page_dir = os.path.join(STATIC_FILE_UPLOAD_PATH, page.directory)
    
    # 检查是否有文件上传
    if not files:
        raise HTTPException(status_code=400, detail="请选择要上传的文件")
    
    for file in files:
        # 检查文件是否为空
        if not file.filename:
            continue  # 跳过空文件名的文件
        
        # 过滤.DS_Store文件
        if os.path.basename(file.filename) == '.DS_Store':
            continue  # 跳过.DS_Store系统文件
        
        # 处理文件夹上传，保持目录结构
        # 当上传文件夹时，file.filename 会包含相对路径
        # 确保正确处理以点开头的文件名（如.git）
        file_path = os.path.join(page_dir, file.filename)
        
        # 确保文件所在的目录存在
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        # 读取文件内容检查是否为空
        file_content = await file.read()
        
        # 无论文件是否为空，都创建文件（包括以点开头的文件）
        # 重置文件指针到开始位置
        await file.seek(0)
        
        # 保存文件
        with open(file_path, "wb") as buffer:
            if file_content:  # 如果文件有内容
                shutil.copyfileobj(file.file, buffer)
            else:  # 空文件也创建
                buffer.write(b"")
    
    return RedirectResponse(url=f"/admin/static-pages/files/{page_id}", status_code=303)

@router.post("/admin/static-pages/delete-file/{page_id}")
def static_pages_delete_file(
    page_id: int,
    file_path: str = Form(...),
    db: Session = Depends(get_db)
):
    """删除静态网页文件（返回JSON响应）"""
    page = db.query(StaticPage).filter(StaticPage.id == page_id).first()
    if not page:
        return {"success": False, "message": "静态页面不存在"}
    
    # 构建完整文件路径
    full_path = os.path.join(STATIC_FILE_UPLOAD_PATH, page.directory, file_path)
    
    # 检查文件是否存在且在页面目录内
    if os.path.exists(full_path) and full_path.startswith(os.path.join(STATIC_FILE_UPLOAD_PATH, page.directory)):
        try:
            os.remove(full_path)
            return {"success": True, "message": "文件删除成功"}
        except Exception as e:
            return {"success": False, "message": f"删除文件失败: {str(e)}"}
    
    return {"success": False, "message": f"文件不存在或无权删除: {file_path}"}

@router.post("/admin/static-pages/delete-files/{page_id}")
def static_pages_delete_files(
    page_id: int,
    file_paths: List[str] = Form(...),
    db: Session = Depends(get_db)
):
    """批量删除静态网页文件（返回JSON响应）"""
    page = db.query(StaticPage).filter(StaticPage.id == page_id).first()
    if not page:
        return {"success": False, "message": "静态页面不存在"}
    
    page_dir = os.path.join(STATIC_FILE_UPLOAD_PATH, page.directory)
    deleted_count = 0
    
    # 遍历删除每个文件
    for file_path in file_paths:
        # 构建完整文件路径
        full_path = os.path.join(page_dir, file_path)
        
        # 安全检查：确保文件在页面目录内
        if os.path.exists(full_path) and full_path.startswith(page_dir):
            try:
                os.remove(full_path)
                deleted_count += 1
            except Exception:
                # 忽略单个文件删除失败，继续删除其他文件
                pass
    
    return {"success": True, "message": f"批量删除成功，共删除 {deleted_count} 个文件"}

@router.get("/static/pages/{directory}/{file_path:path}")
async def serve_static_file(directory: str, file_path: str, request: Request, db: Session = Depends(get_db)):
    """提供静态页面文件访问"""
    # 检查页面状态，只有启用的页面才能访问其文件
    page = db.query(StaticPage).filter(StaticPage.directory == directory).first()
    if page and not page.status:
        # 页面存在但被禁用，返回404页面
        return templates.TemplateResponse("404.html", {"request": request}, status_code=404)
    
    # 构建完整文件路径
    full_path = os.path.join(STATIC_FILE_UPLOAD_PATH, directory, file_path)
    
    # 检查文件是否存在
    if os.path.exists(full_path) and os.path.isfile(full_path):
        # 获取文件扩展名以确定MIME类型
        file_ext = os.path.splitext(file_path)[1].lower()
        
        # 返回文件响应
        return FileResponse(path=full_path)
    else:
        # 提供404页面而不是抛出异常
        return templates.TemplateResponse("404.html", {"request": request}, status_code=404)